package failover

import (
	"context"
	"jk-time/webook/internal/service/sms"
	"sync/atomic"
)

type TimeoutFailoverSMSService struct {
	svcs []sms.Service
	idx  int32
	//连续超时的个数
	cnt int32

	//阈值
	//连续超过超时这个数字，切换
	threshold int32
}

func NewTimeoutFailoverSMSService(svcs []sms.Service, threshold int32) *TimeoutFailoverSMSService {
	return &TimeoutFailoverSMSService{
		svcs:      svcs,
		idx:       0,
		cnt:       0,
		threshold: threshold,
	}
}
func (t *TimeoutFailoverSMSService) Send(ctx context.Context, tplId string, args []string, numbers ...string) error {
	if atomic.LoadInt32(&t.cnt) >= t.threshold {
		idx := atomic.LoadInt32(&t.idx)
		//触发切换，计算新的下标
		newIdx := (idx + 1) % int32(len(t.svcs))
		// CAS 操作失败。说明有人切换了，这里不需要检测返回值
		if atomic.CompareAndSwapInt32(&t.idx, idx, newIdx) {
			//说明你切换了
			atomic.StoreInt32(&t.cnt, 0)
		}
	}
	svc := t.svcs[t.idx]
	//当前使用的svc
	err := svc.Send(ctx, tplId, args, numbers...)
	switch err {
	case context.DeadlineExceeded:
		atomic.AddInt32(&t.cnt, 1)
	case nil:
		atomic.StoreInt32(&t.cnt, 0)
	default:
		// 超时，可能是偶发的，我尽量再试试
		// 非超时，直接下一个
	}
	return err
}
